package com.nwpu.coursesupport.service.imple;

import com.nwpu.coursesupport.criteria.ClassViewSearchCriteria;
import com.nwpu.coursesupport.criteria.CurrentLessonSearchCriteria;
import com.nwpu.coursesupport.criteria.LessonSearchCriteria;
import com.nwpu.coursesupport.entity.Class;
import com.nwpu.coursesupport.entity.Class.ClassDate;
import com.nwpu.coursesupport.entity.Class.DateItem;
import com.nwpu.coursesupport.entity.Lesson;
import com.nwpu.coursesupport.entity.bean.JSONResult;
import com.nwpu.coursesupport.enumeration.LessonCreateType;
import com.nwpu.coursesupport.enumeration.LessonStatus;
import com.nwpu.coursesupport.enumeration.LessonType;
import com.nwpu.coursesupport.exception.ClassDealException;
import com.nwpu.coursesupport.mapper.ClassMapper;
import com.nwpu.coursesupport.mapper.LessonMapper;
import com.nwpu.coursesupport.pagination.PageBounds;
import com.nwpu.coursesupport.service.AbstractService;
import com.nwpu.coursesupport.service.param.IDListParam;
import com.nwpu.coursesupport.service.param.IDParam;
import com.nwpu.coursesupport.service.param.LessonServiceParam;
import com.nwpu.coursesupport.tool.DateUtil;
import com.nwpu.coursesupport.tool.ServiceUtil;
import com.nwpu.coursesupport.tool.UpdateUtil;
import com.nwpu.coursesupport.view.ClassView;
import com.nwpu.coursesupport.view.LessonView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class LessonService extends AbstractService{
    @Autowired
    private LessonMapper lessonMapper;
    @Autowired
    private ClassMapper classMapper;

    protected static Logger logger = LoggerFactory.getLogger(LessonService.class);

    public JSONResult detail(IDParam p) throws Exception{
        JSONResult rst = new JSONResult();
        rst.fail();
        if (p == null || p.getId() <= 0){
        	logger.error("参数有误");
            rst.fail("参数有误");
            return rst;
        }

        Lesson lesson = this.lessonMapper.findById(p.getId());

        rst.addData("lesson", lesson);
        rst.success();
        return rst;
    }

    public JSONResult detailView(IDParam p){
    	 JSONResult rst = new JSONResult();
         rst.fail();
         if (p == null || p.getId() <= 0){
        	 logger.error("参数有误");
             rst.fail("参数有误");
             return rst;
         }

         LessonView view=this.lessonMapper.findViewById(p.getId());

         if(view==null){
        	 logger.error("该课堂不存在");
        	 return rst.fail("该课堂不存在");
         }
         rst.addData("lesson", view);
         rst.success();
         return rst;
    }

    public JSONResult listView(LessonServiceParam.SearchParam p){
        JSONResult rst = new JSONResult();
        rst.fail();

        if (p == null){
        	logger.error("参数为空");
            return rst.fail("参数有误");
        }

        LessonSearchCriteria sc = p.getSearch();
        if (sc == null || sc.getClassId()<=0){
        	logger.error("查询参数为空");
           rst.fail("查询参数有误");
        }
        if(sc.getType()==null){
        	sc.setType(LessonType.THEORY);
        }
        if (p.getPageNo() <= 0){
			p.setPageNo(1);
		}

        int pageSize = 10;
        int totalCount =this.lessonMapper.count(sc);
        int pageCount = totalCount % pageSize > 0 ? totalCount / pageSize + 1 : totalCount / pageSize;
		if (p.getPageNo() > pageCount){
			p.setPageNo(pageCount);
		}
		PageBounds page = new PageBounds();
        page.setNumber(p.getPageNo());
        page.setSize(pageSize);

        List<Lesson> list = this.lessonMapper.find(sc, page);
        if (list == null){
        	logger.error("数据查询失败");
            return rst.fail("数据查询失败");
        }
        ServiceUtil.parseLesson(list);
        ClassViewSearchCriteria cvsc=new ClassViewSearchCriteria();
        cvsc.setClassId(sc.getClassId());
        ClassView view=this.classMapper.getClassView(cvsc);
        if(view==null){
        	logger.error("ClassView不存在");
			return rst.fail("该班级不存在");
		}
        view.setTheoryDate(ServiceUtil.DeserializeDate(view.getTheoryDateBytes()));
        view.setLabDate(ServiceUtil.DeserializeDate(view.getLabDateBytes()));
        rst.addData("classView", view);
        rst.addData("list", list);
        rst.addData("pageNo", p.getPageNo());
        rst.addData("allpages", pageCount);
        rst.success();
        return rst;
    }

    public JSONResult listData(LessonServiceParam.SearchParam p){
        JSONResult rst = new JSONResult();
        rst.fail();

        if (p == null){
        	logger.error("参数有误");
            return rst.fail("参数有误");
        }

        LessonSearchCriteria sc = p.getSearch();
        if (sc == null || sc.getClassId()==null){
        	logger.error("查询参数有误");
            return rst.fail("查询参数有误");
        }
        if(sc.getType()==null){
        	sc.setType(LessonType.THEORY);
        }
        if (p.getPageNo() <= 0){
			p.setPageNo(1);
		}

        int pageSize = 10;
        int totalCount =this.lessonMapper.count(sc);
        int pageCount = totalCount % pageSize > 0 ? totalCount / pageSize + 1 : totalCount / pageSize;
		if (p.getPageNo() > pageCount){
			p.setPageNo(pageCount);
		}
		PageBounds page = new PageBounds();
        page.setNumber(p.getPageNo());
        page.setSize(pageSize);

        List<Lesson> list = this.lessonMapper.find(sc, page);
        if (list == null){
        	logger.error("数据查询失败");
            return rst.fail("数据查询失败");
        }
        ServiceUtil.parseLesson(list);
        rst.addData("list", list);
        rst.addData("pageNo", p.getPageNo());
        rst.addData("allpages", pageCount);
        rst.success();
        return rst;
    }

    public JSONResult create(LessonServiceParam.CreateParam p) throws Exception{
        JSONResult rst = new JSONResult();
        rst.fail();

        if (p == null||p.getClassId()==null||p.getType()==null){
        	logger.error("参数有误");
            return rst.fail("参数有误");
        }

        Class c=this.classMapper.findById(p.getClassId());
        if(c==null){
        	logger.error("该班级不存在");
        	return rst.fail("该班级不存在");
        }

        if(p.getBeginDate().after(p.getEndDate())||p.getBeginDate().equals(p.getEndDate())){
        	logger.error("该课程的开课时间有误");
        	return rst.fail("该课程的开课时间有误");
        }

        Lesson lesson = new Lesson();
        lesson.setBeginDate(p.getBeginDate());
        lesson.setEndDate(p.getEndDate());
        lesson.setDurationCourse(DateUtil.getDuration(p.getBeginDate(),p.getEndDate()));
        lesson.setClassId(c.getId());
        lesson.setClassName(c.getName());
        lesson.setType(p.getType());
        lesson.setCreateType(LessonCreateType.NEWADD);
        lesson.setLocation(p.getLocation());

        if (!this.lessonMapper.save(lesson)){
        	logger.error("保存失败");
            return rst.fail("保存失败");
        }

        /*修改大班的信息*/
        if(p.getType()==LessonType.THEORY && c.getHasTheory() == 0){
        	ClassDate cd = new ClassDate();
        	cd.setSumWeeks(1);
        	cd.setTimeOfWeek(1);
        	DateItem di = new DateItem();
        	di.setBegin(p.getBeginDate());
        	di.setEnd(p.getEndDate());
        	di.setLocation(p.getLocation());
        	ArrayList<DateItem> date = new ArrayList<DateItem>();
        	date.add(di);
        	cd.setDate(date);
        	String dateBytes=ServiceUtil.serializeDate(cd);

        	c.setHasTheory(1);
        	c.setTheoryDateBytes(dateBytes);
        	if(!this.classMapper.updateClassLesson(c)){
        		logger.error("更新班级信息失败");
        		throw new ClassDealException("更新班级信息失败");
        	}
        }
        if(p.getType()==LessonType.LAB && c.getHasLab() == 0){
        	ClassDate cd = new ClassDate();
        	cd.setSumWeeks(1);
        	cd.setTimeOfWeek(1);
        	DateItem di = new DateItem();
        	di.setBegin(p.getBeginDate());
        	di.setEnd(p.getEndDate());
        	di.setLocation(p.getLocation());
        	ArrayList<DateItem> date = new ArrayList<DateItem>();
        	date.add(di);
        	cd.setDate(date);
        	String dateBytes=ServiceUtil.serializeDate(cd);
        	c.setHasLab(1);
        	c.setLabDateBytes(dateBytes);
        	if(!this.classMapper.updateClassLesson(c)){
        		logger.error("更新班级信息失败");
        		throw new ClassDealException("更新班级信息失败");
        	}
        }

        rst.addData("lesson", lesson);
        rst.success();
        return rst;
    }

    public JSONResult update(LessonServiceParam.UpdateParam p) throws Exception{
        JSONResult rst = new JSONResult();
        rst.fail();

        if (p == null || p.getId() <= 0){
        	logger.error("参数有误");
            return rst.fail("参数有误");
        }

        Lesson lesson = this.lessonMapper.findById(p.getId());
        if (lesson == null){
        	logger.error("记录不存在或已被删除");
            return rst.fail("记录不存在或已被删除");
        }

        if (UpdateUtil.setValues(lesson, p) > 0){
        	 if (!this.lessonMapper.update(lesson)){
        		 logger.error("保存失败");
                 return rst.fail("保存失败");
             }
        }

        rst.addData("lesson", lesson);
        rst.success();
        return rst;
    }

    public JSONResult remove(IDParam p) throws Exception{
        JSONResult rst = new JSONResult();
        rst.fail();

        if (p == null || p.getId() <= 0){
        	logger.error("参数有误");
            rst.fail("参数有误");
            return rst;
        }


        Lesson lesson = this.lessonMapper.findById(p.getId());
        if (lesson == null){
        	logger.error("记录不存在或已被删除");
            return rst.fail("记录不存在或已被删除");
        }

        if (!this.lessonMapper.delete(p.getId())){
        	logger.error("删除失败");
            return rst.fail("删除失败");
        }
        rst.addData("lesson", lesson);
        rst.success();
        return rst;
    }

    public JSONResult removeAll(IDListParam p) throws Exception{
        JSONResult rst = new JSONResult();
        rst.fail();

        if (p == null || p.getIds() == null || p.getIds().isEmpty()){
        	logger.error("参数有误");
            rst.fail("参数有误");
            return rst;
        }

        this.lessonMapper.batchDelete(p.getIds());

        rst.success();
        return rst;
    }


    public JSONResult currentLessonByTeacher(CurrentLessonSearchCriteria sc){
    	JSONResult rst=new JSONResult();
    	rst.fail();

    	if(sc==null||sc.getId()<=0){
    		logger.error("参数失败");
    		return rst.fail("参数失败");
    	}
    	if(sc.getSeacherDate()==null){
    		sc.setSeacherDate(new Date());
    	}
    	sc.setBegin(DateUtil.getBeginOfDate(sc.getSeacherDate()));
    	sc.setEnd(DateUtil.getEndOfDate(sc.getSeacherDate()));
    	List<LessonView> list=this.lessonMapper.findCurrentLessonByTeacher(sc);
    	list.forEach(item->{
    		Date now = new Date();
			if (item.getEndDate().before(now)) {// 结束时间小于现在
				item.setStatus(LessonStatus.FINISHED);
			} else if (item.getBeginDate().after(now)) {
				item.setStatus(LessonStatus.NOTSTART);
			} else if (item.getBeginDate().before(now) && item.getEndDate().after(now)) {
				item.setStatus(LessonStatus.INPROGRESS);
			}
    	});
    	rst.success();
    	rst.addData("list", list);
    	return rst;

    }
    public JSONResult currentLessonByAssistant(CurrentLessonSearchCriteria sc){
    	JSONResult rst=new JSONResult();
    	rst.fail();

    	if(sc==null||sc.getId()<=0){
    		logger.error("参数失败");
    		return rst.fail("参数失败");
    	}
    	if(sc.getSeacherDate()==null){
    		sc.setSeacherDate(new Date());
    	}
    	sc.setBegin(DateUtil.getBeginOfDate(sc.getSeacherDate()));
    	sc.setEnd(DateUtil.getEndOfDate(sc.getSeacherDate()));
    	List<LessonView> list=this.lessonMapper.findCurrentLessonByAssistant(sc);
    	list.forEach(item->{
    		Date now = new Date();
			if (item.getEndDate().before(now)) {// 结束时间小于现在
				item.setStatus(LessonStatus.FINISHED);
			} else if (item.getBeginDate().after(now)) {
				item.setStatus(LessonStatus.NOTSTART);
			} else if (item.getBeginDate().before(now) && item.getEndDate().after(now)) {
				item.setStatus(LessonStatus.INPROGRESS);
			}
    	});

    	rst.success();
    	rst.addData("list", list);
    	return rst;

    }
    public JSONResult currentLessonByStudent(CurrentLessonSearchCriteria sc){
    	JSONResult rst=new JSONResult();
    	rst.fail();

    	if(sc==null||sc.getId()<=0){
    		logger.error("参数失败");
    		return rst.fail("参数失败");
    	}
    	if(sc.getSeacherDate()==null){
    		sc.setSeacherDate(new Date());
    	}
    	sc.setBegin(DateUtil.getBeginOfDate(sc.getSeacherDate()));
    	sc.setEnd(DateUtil.getEndOfDate(sc.getSeacherDate()));
    	List<LessonView> list=this.lessonMapper.findCurrentLessonByStudent(sc);


    	list.forEach(item->{
    		Date now = new Date();
			if (item.getEndDate().before(now)) {// 结束时间小于现在
				item.setStatus(LessonStatus.FINISHED);
			} else if (item.getBeginDate().after(now)) {
				item.setStatus(LessonStatus.NOTSTART);
			} else if (item.getBeginDate().before(now) && item.getEndDate().after(now)) {
				item.setStatus(LessonStatus.INPROGRESS);
			}
    	});


    	rst.success();
    	rst.addData("list", list);
    	return rst;

    }

}
